// 全局变量
var XbzDesigner = {};

// 初始化相关变量
layui.define([ 'all' ], function(exports) {
	XbzDesigner.$ = layui.jquery;
	XbzDesigner.layui = layui;
	XbzDesigner.layuiForm = layui.form;
	XbzDesigner.layuiLayer = layui.layer;
});

// 扩展String方法
String.prototype.formatText = function(...args) {
	if (args.length === 0) {
		return this;
	}
	var ns = this;
	for (var i = 0; i < args.length; i++) {
		var regex = new RegExp("\\{" + i + "\\}", "g");
		ns = ns.replace(regex, args[i]);
	}
	return ns;
};

(function($, XDE) {
	// 自定义的Map
	class XbzMap {
		// 构造方法
		constructor() {
			this.container = Object.create(null);
		}
		
		// put方法
		put(key, value) {
			this.container[key] = value;
		};
		
		// remove方法
		remove(key) {
			if (this.container.hasOwnProperty(key)) {
				delete this.container[key];
			}
		};
		
		// get方法
		get(key) {
			return this.container[key];
		};
		
		// size方法
		size() {
			return Object.keys(this.container).length;
		};
		
		// clear方法
		clear() {
			this.container = Object.create(null);
		};
		
		// 遍历方法
		each(callback) {
			for (var key in this.container) {
				callback(key, this.container[key]);
			}
		};
	}
	
	// 解决火狐浏览器在拖拽时打开新标签的问题
	if (document.body) {
		document.body.ondrop = function(event) {
			event.preventDefault();
			event.stopPropagation();
		}
	}
	
	// JS文件目录
	if (!XDE.XBZ_DESIGNER_PREPATH) {
		var jsArray = document.scripts;
		XDE.XBZ_DESIGNER_PREPATH = jsArray[jsArray.length - 1].src.substring(0, jsArray[jsArray.length - 1].src.lastIndexOf("/") + 1);
	}
	
	// 工具方法
	XDE.util = {
		// 是否空元素
		isNull: function(value) {
			// 直接检查 null、undefined、NaN 和空字符串
			return value == null || value === undefined || value !== value || value === '';
		},
		// 是否空数组
		isNullArray: function(value) {
			return this.isNull(value) || (value.length === 0);
		},
		// 获取值
		getValue: function(value, defaultValue) {
			return this.isNull(value) ? defaultValue : value;
		},
		// 加载CSS
		loadCSS: function(href) {
			var head = document.getElementsByTagName("head")[0];
			var link = document.createElement("link");
			link.rel = "stylesheet";
			link.type = "text/css";
			link.href = href;
			head.appendChild(link);
		},
		// 加载JS
		loadJS: function(href) {
			document.write('<script type="text/javascript" src="{0}"></script>'.formatText(href));
		},
		// 加载插件
		loadAss: function(ass) {
			this.loadJS("{0}ass/{1}/{1}.js".formatText(XDE.XBZ_DESIGNER_PREPATH, ass));
		},
		// UUID方法
		uuid: function() {
			var t = new Date().getTime();
			var u = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(x) {
				var r = (t + Math.random() * 16) % 16 | 0;
				t = Math.floor(t / 16);
				return (x == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
			});
			return u.replace(/-/g, "").toString().toUpperCase();
		}
	};
	
	// 配置容器
	XDE.ctx = new XbzMap(); 
	
	// 组件容器
	XDE.ass = new XbzMap(); 
	
	// 渲染方法
	XDE.render = function() {
		XDE.layuiForm.render();
	};
	
	// 界面预览
	XDE.preview = function() {
		var data = getData();
		var json = JSON.stringify(data);
		window.localStorage.setItem("XBZ_DESIGNER_JSON", json);
		window.open("XbzDesignerPreview.html", "_blank");
	};
	
	// 界面构建
	XDE.buildView = function(elementId, data) {
		// 界面构建
		if (!XDE.util.isNullArray(data)) {
			var viewContainer = document.getElementById(elementId);
			for (var i = 0; i < data.length; i++) {
				var node = data[i];
				var ass = XDE.ass.get(node.tag);
				var tag = ass.createElement(node);
				viewContainer.appendChild(tag.element);
			}
		}
		
		// 界面渲染
		XDE.render();
	}
	
	// 设置拖拽
	XDE.sortable = function(element) {
		new Sortable(element, {
			group : {
				name : 'XbzDesignerGroup',
				pull : true
			},
			handle : '.widget-view-drag',
			animation : 150,
			onAdd : function(evt) {
				addTag(evt);
			}
		});
	};
	
	// 初始化方法
	XDE.init = function() {
		// 界面组件
		$(".components-draggable").each(function() {
			Sortable.create(this, {
				group : {
					name : "XbzDesignerGroup",
					pull : 'clone',
					put : false,
				},
				sort : false,
				animation : 150,
				// 可拖拽的标签
				draggable : ".components-item"
			});
		});

		// 界面容器
		XDE.sortable(document.getElementById("XbzDesignerContainer"));

		// 界面渲染
		XDE.render();
	};
	
	// 阻止点击事件的冒泡传播
	function stopBubbling(e) {
		e = e || window.event;
		if (e.stopPropagation) {
			e.stopPropagation();   // 阻止事件的冒泡传播
		} else {
			e.cancelBubble = true; // IE兼容
		}
	}
	
	// 点击事件
	function clickBind(tagElement) {
		$(tagElement).click(function(event) {
			if (XDE.ActiveElement.getAttribute("x-id") != tagElement.getAttribute("x-id")) {
				activeBind(tagElement);
			}
			stopBubbling(event);
		});
	}
	
	// 复制节点
	function copyElement(copyElement) {
		// 节点信息（旧）
		var copyId = copyElement.getAttribute("x-id");
		var copyTag = copyElement.getAttribute("x-tag");
		var copyNode = getNode(copyId);

		// 组件执行器
		var tagAss = XDE.ass.get(copyTag);

		// 节点信息（新）
		var newNode = tagAss.buildNode(copyNode, true);
		var newTag = tagAss.createElement(newNode);

		// 新节点放入容器
		setNode(newTag.node);

		// 嵌套拖拽
		var childContainers = newTag.element.getElementsByClassName("XbzDesignerChildContainer");
		for (i = 0; i < childContainers.length; i++) {
			XDE.sortable(childContainers[i]);
		}

		// 子元素可拖拽
		$(newTag.element).find("[x-drag='1']").each(function() {
			var childElement = $(this).get(0);
			// 点击事件
			clickBind(childElement);
			// 组件操作
			activeBind(childElement);
		});

		// 点击事件
		clickBind(newTag.element);

		// 组件操作
		activeBind(newTag.element);

		return newTag.element;
	}
	
	// 组件设置
	function settingTag(tag, id) {
		$("#XbzDesignerTagSetting").attr("src", "{0}ass/{1}/{1}.html?id={2}&t={3}".formatText(XDE.XBZ_DESIGNER_PREPATH, tag, id, Math.random()));
	}
	
	// 组件操作
	function activeBind(tagElement) {
		var jqueryElement = null;
		if (XDE.ActiveElement) {
			jqueryElement = $(XDE.ActiveElement);
			jqueryElement.children('.widget-view-drag').remove();
			jqueryElement.children('.widget-view-action').remove();
			jqueryElement.removeClass('widget-view-ctrl-action');
		}
		XDE.ActiveElement = tagElement;
		jqueryElement = $(XDE.ActiveElement);
		jqueryElement.addClass('widget-view-ctrl-action');
		
		// 组件设置
		settingTag(tagElement.getAttribute("x-tag"), tagElement.getAttribute("x-id"));

		// 拖动按钮
		if (jqueryElement.find(".widget-view-drag").length == 0) {
			var widgetViewDrag = $('<div><i class="layui-icon layui-icon-screen-full"></i></div>');
			widgetViewDrag.addClass('widget-view-drag');
			jqueryElement.prepend(widgetViewDrag);
		}

		// 复制与删除
		if (jqueryElement.find(".widget-view-action").length == 0) {
			var widgetViewAction = $('<div></div>');
			widgetViewAction.addClass('widget-view-action');
			jqueryElement.prepend(widgetViewAction);

			// 复制按钮
			var widgetViewActionCopyBtn = $('<i class="layui-icon layui-icon-file"></i>');
			widgetViewAction.append(widgetViewActionCopyBtn);
			
			// 复制按钮的点击
			widgetViewActionCopyBtn.click(function() {
				var newElement = copyElement(tagElement);
				jqueryElement.parent().append(newElement);
			});
			
			// 删除按钮
			var widgetViewActionDeleteBtn = $('<i class="layui-icon layui-icon-delete"></i>');
			widgetViewAction.append(widgetViewActionDeleteBtn);
			
			// 删除按钮的点击事件
			widgetViewActionDeleteBtn.click(function() {
				tagElement.remove();
			});
		}
	}
	
	// 设置组件
	function setNode(node) {
		XDE.ctx.put(node.id, node);

		// 子节点
		var childs = node.childs;
		if (!XDE.util.isNullArray(childs)) {
			for (var i = 0; i < childs.length; i++) {
				setNode(childs[i]);
			}
		}
	}

	// 获取组件
	function getNode(id) {
		// 节点信息
		var node = XDE.ctx.get(id);

		// 子节点
		if (node.childs) {
			var childs = [];
			$("[x-id='" + id + "']").children("[x-id]").each(function() {
				childs.push(getNode($(this).attr("x-id")));
			});
			node.childs = childs;
		}

		// 返回结果
		return node;
	}
	
	// 获取数据
	function getData() {
		var data = [];
		$(document.getElementById("XbzDesignerContainer")).children("[x-id]").each(function() {
			data.push(getNode($(this).attr("x-id")));
		});
		return data;
	}
	
	// 创建组件
	function createTag(node) {
		var tagAss = XDE.ass.get(node.tag);
		var newTag = tagAss.createElement(node);
		
		// 点击事件
		clickBind(newTag.element);
		
		// 组件操作
		activeBind(newTag.element);
		
		return newTag;
	}

	// 添加组件
	function addTag(evt) {
		var item = evt.item;
		var itemId = item.getAttribute("x-id");
		var itemTag = item.getAttribute("x-tag");
		if (itemTag) {
			if (XDE.util.isNull(itemId)) {
				// 创建组件
				var newTag = createTag({
					tag : itemTag
				});

				// 父节点ID
				newTag.node.pid = XDE.util.getValue(item.parentNode.getAttribute("x-id"), "0");

				// 放入容器
				setNode(newTag.node);
				
				// 替换元素
				item.parentNode.replaceChild(newTag.element, item);

				// 嵌套拖拽
				var childContainers = newTag.element.getElementsByClassName("XbzDesignerChildContainer");
				for (i = 0; i < childContainers.length; i++) {
					var childElement = childContainers[i];
					XDE.sortable(childElement);
					
				}
			} else {
				// 节点信息
				var node = XDE.ctx.get(itemId);
				
				// 父节点ID
				node.pid = XDE.util.getValue(item.parentNode.getAttribute("x-id"), "0");
			}

			// 重新渲染
			XDE.render();
		}
	}
	
	// 加载组件
	XDE.util.loadAss("input");
	XDE.util.loadAss("grid1");
	XDE.util.loadAss("grid2");
	XDE.util.loadAss("grid3");
	XDE.util.loadAss("grid4");
})(XbzDesigner.$, XbzDesigner);